package com.haidechizi.fastadmin.modules.gen.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.haidechizi.fastadmin.common.page.PageDto;
import com.haidechizi.fastadmin.common.utils.PageInfo;
import com.haidechizi.fastadmin.common.utils.StringUtils;
import com.haidechizi.fastadmin.modules.gen.dao.GenSchemeDao;
import com.haidechizi.fastadmin.modules.gen.dao.GenTableColumnDao;
import com.haidechizi.fastadmin.modules.gen.dao.GenTableDao;
import com.haidechizi.fastadmin.modules.gen.entity.GenConfig;
import com.haidechizi.fastadmin.modules.gen.entity.GenScheme;
import com.haidechizi.fastadmin.modules.gen.entity.GenTable;
import com.haidechizi.fastadmin.modules.gen.entity.GenTableColumn;
import com.haidechizi.fastadmin.modules.gen.entity.GenTemplate;
import com.haidechizi.fastadmin.modules.gen.service.GenSchemeService;
import com.haidechizi.fastadmin.modules.gen.util.GenUtils;
import com.haidechizi.fastadmin.modules.sys.entity.SysMenu;
import com.haidechizi.fastadmin.modules.sys.service.SysMenuService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 生成代码的方案
 */
@Service
@Transactional(readOnly = true)
public class GenSchemeServiceImpl extends ServiceImpl<GenSchemeDao, GenScheme> implements GenSchemeService {

    @Autowired
    private GenSchemeDao genSchemeDao;

    @Autowired
    private GenTableDao genTableDao;

    @Autowired
    private GenTableColumnDao genTableColumnDao;

    @Autowired
    private SysMenuService sysMenuService;

    @Value("${jdbc.type:mysql}")
    private String jdbcType;

    /**
     * 分页查询
     *
     * @param pageDto
     * @param genScheme
     * @return
     */
    @Override
    public PageInfo findPage(PageDto pageDto, GenScheme genScheme) {
        Wrapper<GenScheme> wrapper;
        Page<GenScheme> page = this.selectPage(
                pageDto.cover2Page(),
                wrapper = new EntityWrapper<GenScheme>()
                        .eq(StringUtils.isNotBlank(genScheme.getName()), "name", genScheme.getName())
        );
        int count = super.selectCount(wrapper);
        page.setTotal(count);
        return new PageInfo(page);
    }

    /**
     * 保存
     *
     * @param genScheme
     * @return
     */
    @Transactional
    public String save(GenScheme genScheme) {
        genSchemeDao.insert(genScheme);
        // 生成代码
        if ("1".equals(genScheme.getFlag())) {
            // 创建菜单
            createMenu(genScheme);
            return generateCode(genScheme);
        }
        return "";
    }

    /**
     * 更新
     *
     * @param genScheme
     */
    @Override
    @Transactional
    public String update(GenScheme genScheme) {
        genSchemeDao.updateById(genScheme);
        // 生成代码
        if ("1".equals(genScheme.getFlag())) {
            createMenu(genScheme);
            return generateCode(genScheme);
        }
        return "";

    }

    /**
     * 生成代码
     *
     * @param genScheme
     * @return
     */
    private String generateCode(GenScheme genScheme) {
        genScheme.setJdbcType(jdbcType);
        StringBuilder result = new StringBuilder();

        // 查询主表及字段列
        GenTable genTable = genTableDao.selectById(genScheme.getGenTableId());
        List<GenTableColumn> columnList = genTableColumnDao.selectList(
                new EntityWrapper<GenTableColumn>().eq("gen_table_id", genTable.getId()));
        genTable.setColumnList(columnList);

        // 获取所有代码模板
        GenConfig config = GenUtils.getConfig();

        // 获取模板列表
        List<GenTemplate> templateList = GenUtils.getTemplateList(config, genScheme.getCategory(), false);
        List<GenTemplate> childTableTemplateList = GenUtils.getTemplateList(config, genScheme.getCategory(), true);

        // 如果有子表模板，则需要获取子表列表
        if (childTableTemplateList.size() > 0) {
            GenTable parentTable = new GenTable();
            parentTable.setParentTable(genTable.getName());
            List<GenTable> childTableList = genTableDao.selectList(
                    new EntityWrapper<GenTable>().eq("parent_table", genTable.getName()));
            genTable.setChildList(childTableList);
        }

        // 生成子表模板代码
        for (GenTable childTable : genTable.getChildList()) {
            childTable.setParent(genTable);
            List<GenTableColumn> childColumnList = genTableColumnDao.selectList(
                    new EntityWrapper<GenTableColumn>().eq("gen_table_id", childTable.getId()));
            childTable.setColumnList(childColumnList);
            genScheme.setGenTable(childTable);
            Map<String, Object> childTableModel = GenUtils.getDataModel(genScheme);
            for (GenTemplate tpl : childTableTemplateList) {
                result.append(GenUtils.generateToFile(tpl, childTableModel, "1".equals(genScheme.getReplaceFile()) ? true : false));
            }
        }

        // 生成主表模板代码
        genScheme.setGenTable(genTable);
        Map<String, Object> model = GenUtils.getDataModel(genScheme);
        for (GenTemplate tpl : templateList) {
            result.append(GenUtils.generateToFile(tpl, model, "1".equals(genScheme.getReplaceFile()) ? true : false));
        }
        return result.toString();
    }

    /**
     * 创建菜单和权限
     *
     * @param genScheme
     */
    private void createMenu(GenScheme genScheme) {
        // 校验当前菜单是否创建
        List<SysMenu> sysMenuList = sysMenuService.queryMenuByName(genScheme.getFunctionName());
        if (CollectionUtils.isNotEmpty(sysMenuList)) {
            return;
        }
        // 菜单
        SysMenu sysMenu = new SysMenu();
        sysMenu.setParentId(0L);
        sysMenu.setName(genScheme.getFunctionName());
        sysMenu.setType(1);
        sysMenu.setOrderNum(100);
        GenTable genTable = genTableDao.selectById(genScheme.getGenTableId());
        String className = StringUtils.uncapitalize(genTable.getClassName());
        String lastPackageName = StringUtils.substringAfterLast(genScheme.getPackageName(), ".");
        String permPrefix = genScheme.getModuleName() + ":" + className;
        sysMenu.setPerms(permPrefix + ":list");
        sysMenu.setUrl(lastPackageName + "/" + genScheme.getModuleName() + "/" + className + ".html");
        sysMenuService.insert(sysMenu);

        // 创建新增权限
        SysMenu sysMenu1 = new SysMenu();
        sysMenu1.setPerms(permPrefix + ":save");
        sysMenu1.setParentId(sysMenu.getMenuId());
        sysMenu1.setName("新增");
        sysMenu1.setType(2);
        sysMenu1.setOrderNum(10);
        sysMenuService.insert(sysMenu1);

        // 修改权限
        sysMenu1.setMenuId(null);
        sysMenu1.setPerms(permPrefix + ":update");
        sysMenu1.setParentId(sysMenu.getMenuId());
        sysMenu1.setName("修改");
        sysMenu1.setType(2);
        sysMenu1.setOrderNum(20);
        sysMenuService.insert(sysMenu1);

        // 删除权限
        sysMenu1.setMenuId(null);
        sysMenu1.setPerms(permPrefix + ":delete");
        sysMenu1.setParentId(sysMenu.getMenuId());
        sysMenu1.setName("删除");
        sysMenu1.setType(2);
        sysMenu1.setOrderNum(30);
        sysMenuService.insert(sysMenu1);

        // 查看权限
        sysMenu1.setMenuId(null);
        sysMenu1.setPerms(permPrefix + ":info");
        sysMenu1.setParentId(sysMenu.getMenuId());
        sysMenu1.setName("查看");
        sysMenu1.setType(2);
        sysMenu1.setOrderNum(40);
        sysMenuService.insert(sysMenu1);

    }
}
